package com.yuanian.timingwheel.model.task.executetask;

import com.alibaba.fastjson.JSONObject;
import com.yuanian.timingwheel.context.SpringContext;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;

/**
 * 单机任务执行的方法
 */
public class LocalTaskExecutor implements TaskExecutor {

    //执行的bean类的方法
    private String executionMethod;

    //执行的bean类
    private String beanName;

    //需要执行的入参
    private Object[] args;

    //入参的类型
    private Class[] paramClazz;

    //附加的参数，比如threadlocal里userid等等，用来还原当时执行的环境
    private Object[] attachArgs;

    public LocalTaskExecutor() {

    }

    public LocalTaskExecutor(String executionMethod, String beanName, Object[] args) {
        this.executionMethod = executionMethod;
        this.beanName = beanName;
        this.args = args;
        if (args == null) {
            this.paramClazz = null;
        } else {
            this.paramClazz = new Class[this.args.length];
            for (int i = 0; i < args.length; i++) {
                this.paramClazz[i] = args[i].getClass();
            }
        }

    }

    public LocalTaskExecutor(String executionMethod, String beanName, Object[] args, Class[] paramClazz) {
        this.executionMethod = executionMethod;
        this.beanName = beanName;
        this.args = args;
        this.paramClazz = paramClazz;
    }

    public Object execute() {
        Object obj = SpringContext.getBean(beanName);
        if (obj == null) {
            return null;
        }
        try {
            Method method = obj.getClass().getDeclaredMethod(executionMethod, paramClazz);
            method.setAccessible(true);
            //实体类转换
            if (args != null) {
                for (int i = 0; i < args.length; i++) {
                    Class curClazz = args[i].getClass();
                    if (curClazz == LinkedHashMap.class) {
                        args[i] = getBusinessData(paramClazz[i], args[i]);
                    }
                }
            }
            return method.invoke(obj, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Object getBusinessData(Class clz, Object obj) {
        return JSONObject.parseObject(JSONObject.toJSONString(obj), clz);
    }

    public String getExecutionMethod() {
        return executionMethod;
    }

    public void setExecutionMethod(String executionMethod) {
        this.executionMethod = executionMethod;
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    public Object[] getArgs() {
        return args;
    }

    public void setArgs(Object[] args) {
        this.args = args;
    }

    public Class[] getParamClazz() {
        return paramClazz;
    }

    public void setParamClazz(Class[] paramClazz) {
        this.paramClazz = paramClazz;
    }

    public Object[] getAttachArgs() {
        return attachArgs;
    }

    public void setAttachArgs(Object[] attachArgs) {
        this.attachArgs = attachArgs;
    }
}
